import matplotlib

matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import numpy as np
import ast


# model_names = ['CRISP', 'Virchow2', 'Virchow', 'UNI', 'ours']
# tasks = ['ER', 'Grade', 'HER2', 'Ki67', 'pCR', 'PR']
import pandas as pd
df = pd.read_excel('./results.xlsx')

tasks = df['task'].unique()
model_names = df['model'].unique()
model_datas = {model: [] for model in model_names}

for task in tasks:
    task_model_datas = df[df['task'] == task]
    for model in model_names:
        value_df = task_model_datas[task_model_datas['model'] == model]
        model_datas[model] = np.array(ast.literal_eval(value_df['f1s'].values[0]))

colors = ['#5B4E9D', '#E74C9C', '#FF6B9D', '#FF8B6B', '#FFB84D', '#F4E04D']


# model_datas = {
#     'CRISP': np.concatenate([
#         np.random.uniform(0.80, 0.88, 5),
#         np.random.uniform(0.88, 0.96, 20),
#         np.random.uniform(0.96, 1.0, 10)
#     ]),
#     'Virchow2': np.concatenate([
#         np.random.uniform(0.75, 0.82, 6),
#         np.random.uniform(0.82, 0.92, 18),
#         np.random.uniform(0.92, 1.0, 14)
#     ]),
#     'Virchow': np.concatenate([
#         np.random.uniform(0.65, 0.75, 4),
#         np.random.uniform(0.75, 0.88, 20),
#         np.random.uniform(0.88, 0.98, 16)
#     ]),
#     'UNI': np.concatenate([
#         np.random.uniform(0.78, 0.84, 8),
#         np.random.uniform(0.84, 0.92, 18),
#         np.random.uniform(0.92, 1.0, 10)
#     ]),
#     'CONCH': np.concatenate([
#         np.random.uniform(0.62, 0.70, 3),
#         np.random.uniform(0.70, 0.85, 22),
#         np.random.uniform(0.85, 0.98, 20)
#     ]),
#     'ours': np.concatenate([
#         np.random.uniform(0.42, 0.65, 5),
#         np.random.uniform(0.65, 0.80, 15),
#         np.random.uniform(0.80, 0.98, 25)
#     ])
# }


fig, ax = plt.subplots(figsize=(10, 8))
model_datas_list = [model_datas[model] for model in model_names]

# 绘制箱型图
bp = ax.boxplot(model_datas_list,
                positions=range(1, len(model_names) + 1),
                widths=0.5,
                patch_artist=True,
                showfliers=False,  # 不显示箱型图的异常值点
                boxprops=dict(facecolor='white', edgecolor='gray', linewidth=1.5, alpha=0.7),
                whiskerprops=dict(color='gray', linewidth=1.5),
                capprops=dict(color='gray', linewidth=1.5),
                medianprops=dict(color='darkred', linewidth=2))

# 为每个箱子添加半透明颜色
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)
    patch.set_alpha(0.6)

# 添加散点
for i, model in enumerate(model_names):
    x = np.random.normal(i + 1, 0.08, size=len(model_datas[model]))
    y = model_datas[model]
    ax.scatter(x, y, alpha=0.6, s=50, color=colors[i], edgecolors='white', linewidth=0.5)

# 添加显著性标记（** 表示 p < 0.01）
y_max = max([max(model_datas[m]) for m in model_names])
y_pos = y_max + 0.03
ax.plot([1, 2], [y_pos, y_pos], 'k-', linewidth=1.5)
ax.text(1.5, y_pos + 0.01, '**', ha='center', va='bottom', fontsize=14, fontweight='bold')

# 设置y轴
ax.set_ylabel('F1 Score', fontsize=13, fontweight='bold')
ax.set_ylim([0, 0.8])

# 设置x轴
ax.set_xticks(range(1, len(model_names) + 1))
ax.set_xticklabels(model_names, rotation=45, ha='right', fontsize=11)
ax.set_xlim([0.5, len(model_names) + 0.5])

# 添加网格
ax.grid(axis='y', alpha=0.3, linestyle='--', linewidth=0.8)
ax.set_axisbelow(True)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# 调整布局
plt.tight_layout()
# plt.show()
plt.savefig("png_box.png")